package com.weijun.keepalive.service

import android.app.Service
import android.content.BroadcastReceiver
import android.content.ComponentName
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import android.content.ServiceConnection
import android.os.Build
import android.os.Handler
import android.os.IBinder
import android.os.Looper
import com.weijun.keepalive.ACTION_SCREEN_OFF
import com.weijun.keepalive.ACTION_SCREEN_ON
import com.weijun.keepalive.CLICK_NOTIFICATION
import com.weijun.keepalive.LOCAL_SERVICE_NAME
import com.weijun.keepalive.NOTIFY_LEVEL
import com.weijun.keepalive.R
import com.weijun.keepalive.RunMode
import com.weijun.keepalive.isScreenOn
import com.weijun.keepalive.isServiceRunning
import com.weijun.keepalive.keepAlive
import com.weijun.keepalive.logE
import com.weijun.keepalive.receiver.NotificationClickReceiver
import com.weijun.keepalive.receiver.OnePixelReceiver
import com.weijun.keepalive.utils.MediaPlayerUtil
import com.weijun.keepalive.utils.createNotification

/**
 * @author: weijun
 * date: 2023/7/6
 * description:
 */
internal class LocalService : Service() {

    private var bindRemoteServiceFlag = false //是否绑定了 RemoteService
    private var screenOnFlag = true //屏幕是否亮起，false 时开始播放无声音频
    private lateinit var onePxReceiver :OnePixelReceiver
    private lateinit var screenStateReceiver :ScreenStateReceiver

    private val mHandler by lazy(LazyThreadSafetyMode.NONE){ Handler(Looper.getMainLooper()) }

    private lateinit var mBinder:MyBinder

    private inner class ScreenStateReceiver : BroadcastReceiver() {
        override fun onReceive(context: Context, intent: Intent) {
            "LocalService ScreenStateReceiver:${intent.action}".logE()
            when (intent.action) {
                ACTION_SCREEN_OFF -> {
                    screenOnFlag = false
                    MediaPlayerUtil.play()
                }
                ACTION_SCREEN_ON -> {
                    screenOnFlag = true
                    MediaPlayerUtil.pause()
                }
                else -> {}
            }
        }
    }
    private val remoteServiceConnection = object : ServiceConnection {
        override fun onServiceConnected(name: ComponentName?, service: IBinder?) {
            "LocalService onServiceConnected".logE()
            try {
                if (::mBinder.isInitialized && keepAlive?.notificationConfig?.showFlag == true) {
                    val (title,content,icon) = keepAlive?.notificationConfig!!
                    GuardAidl.Stub.asInterface(service).wakeUp(title,content,icon)
                }
            }catch (e :Exception) {
                e.printStackTrace()
            }
        }

        override fun onServiceDisconnected(name: ComponentName?) {
            "LocalService onServiceDisconnected".logE()
            remoteServiceDisconnect()
        }
    }

    private fun remoteServiceDisconnect(){
        if (applicationContext.isServiceRunning(LOCAL_SERVICE_NAME)) {
            startService(Intent(this@LocalService, RemoteService::class.java))
            bindRemoteServiceFlag = this@LocalService.bindService(
                Intent(this@LocalService, RemoteService::class.java),
                remoteServiceConnection,
                BIND_ABOVE_CLIENT
            )
        }
        if (applicationContext.isScreenOn()) {
            sendBroadcast(Intent(ACTION_SCREEN_ON))
        } else {
            sendBroadcast(Intent(ACTION_SCREEN_OFF))
        }
    }

    private fun playSilentMusic(){
        if (keepAlive?.playMusic == false) {
            return
        }
        MediaPlayerUtil.init(this, R.raw.no_sound){
            if (screenOnFlag) {
                return@init
            }
            if (RunMode.ROGUE == keepAlive?.runMode) {
                MediaPlayerUtil.play()
                return@init
            }
            mHandler.postDelayed({ MediaPlayerUtil.play() },5000)
        }
    }

    private fun sendOnePxReceiver() {
        if (::onePxReceiver.isInitialized.not()) {
            onePxReceiver = OnePixelReceiver()
        }
        registerReceiver(onePxReceiver, IntentFilter().apply {
            addAction("android.intent.action.SCREEN_OFF")
            addAction("android.intent.action.SCREEN_ON")
        })
    }

    private fun screenOnReceiver() {
        if (::screenStateReceiver.isInitialized.not()) {
            screenStateReceiver = ScreenStateReceiver()
        }
        registerReceiver(screenStateReceiver, IntentFilter().apply {
            addAction(ACTION_SCREEN_ON)
            addAction(ACTION_SCREEN_OFF)
        })
    }

    private fun startFrontService() {
        if (keepAlive?.notificationConfig?.showFlag == false) {
            return
        }
        startForeground(NOTIFY_LEVEL, createNotification(
            Intent(applicationContext, NotificationClickReceiver::class.java).apply {
                action = CLICK_NOTIFICATION
            }
        ))
    }

    private fun bindGuardProcess() {
        try {
            bindRemoteServiceFlag = bindService(Intent(this, RemoteService::class.java), remoteServiceConnection, BIND_ABOVE_CLIENT)
        } catch (ignore: Exception) { }
    }

    private fun hideNotification() {
        try {
            if (Build.VERSION.SDK_INT < 25) {
                startService(Intent(this, HideForegroundService::class.java))
            }
        } catch (ignore: Exception) { }
    }

    override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
        "LocalService onStartCommand".logE()
        playSilentMusic() //1.无声音频
        sendOnePxReceiver() //2.像素保活
        screenOnReceiver() //屏幕点亮状态监听，用于单独控制音乐播放
        startFrontService() //3.启用前台服务，提升优先级
        bindGuardProcess() //4.绑定守护进程
        hideNotification() //隐藏服务通知
        keepAlive?.onWorking?.invoke()
        return START_STICKY
    }

    override fun onCreate() {
        super.onCreate()
        "LocalService onCreate".logE()
        if (::mBinder.isInitialized.not()) {
            mBinder = MyBinder()
        }
        screenOnFlag = isScreenOn()
    }

    override fun onDestroy() {
        super.onDestroy()
        "LocalService onDestroy".logE()
        try {
            if (bindRemoteServiceFlag) {
                unbindService(remoteServiceConnection)
            }
        } catch (ignore: Exception) { }
        try {
            unregisterReceiver(onePxReceiver)
            unregisterReceiver(screenStateReceiver)
        } catch (ignore: Exception) { }
        keepAlive?.onStop?.invoke()
    }

    override fun onBind(intent: Intent?): IBinder = mBinder

    private inner class MyBinder : GuardAidl.Stub() {
        override fun wakeUp(title: String?, discription: String?, iconRes: Int) {
            "LocalService wakeUp:$title,$discription".logE()
        }
    }
}